package com.webservice.dao;


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.webservice.utils.UUIDUtil;
import com.webservice.utils.VOXMLMapping;
import com.webservice.vo.IBaseVO;
import com.webservice.vo.impl.DealResultLogInterfaceVO;
import com.webservice.vo.impl.LogInterfaceVO;
import com.webservice.vo.impl.ReturnMsgVo;




public class Pub {
	
	private static Logger logger = Logger.getLogger(Pub.class);
	private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	/**
	 * md5加密
	 * @param str
	 * @return
	 * @throws Exception
	 */
//    public static String encodeByMD5(String str) throws Exception{
//        //确定计算方法
//        MessageDigest md5=MessageDigest.getInstance("MD5");
//        BASE64Encoder base64en = new BASE64Encoder();
//        //加密后的字符串
//        String newstr=base64en.encode(md5.digest(str.getBytes("utf-8")));
//        return newstr;
//    }
    
    /***
     * 小写
     * @param str
     * @return
     */
    public static String getStringtoLower(String str){
    	return str.toLowerCase();
    }
    
    /***
     * 大写
     * @param str
     * @return
     */
    public static String getStringtoUpper(String str){
    	return str.toUpperCase();
    }
    
    /***
     * 首字母大写
     * @param str
     * @return
     */
    public static String firstLetterToUpper(String str){
		char[] array = str.toCharArray();
		array[0] -= 32;
		return String.valueOf(array);
	}
    
    /***
     * 首字母小写
     * @param str
     * @return
     */
    public static String firstLetterToLower(String str){
		char[] array = str.toCharArray();
		array[0] += 32;
		return String.valueOf(array);
	}
    
    /***
     * 得到字段对的类型
     * @param vo
     * @return
     */
    public static Map<String,String> getVOFieldType(IBaseVO  vo){
    	Map<String,String> fieldMap=  new LinkedHashMap<String, String>(); 
    	List<String> retEmpty=new ArrayList<String>();
    	Class<?> clazz=vo.getClass();
		Method[] methods=clazz.getMethods();
		for(int i=0;i<methods.length;i++){
			String methordName=methods[i].getName();
			if(methods[i].getReturnType().getName().equalsIgnoreCase("void")){
				retEmpty.add((String) methordName.subSequence(3, methordName.length()));
			}
		}
		Field[] fa = clazz.getDeclaredFields();
		for (int j = 0; j < fa.length; j++) {
			Class<?> fieldClass = fa[j].getType();
			// 属性类型名称
			String 	 className = fieldClass.getSimpleName();
			// 属性名称
			String fieldName = Pub.firstLetterToUpper(fa[j].getName());
			if(retEmpty.contains(fieldName)){
				fieldMap.put(fieldName, className);
			}
		}
		return fieldMap;
    }
    
    /***
     * 得到当前日期
     * @return
     * @throws Exception
     */
	public static String getCurrTime() {
		Calendar cal = Calendar.getInstance();
//		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String str = format.format(cal.getTime());
		return str;
	}
	
	/***
	 * 得到Timestamp时间
	 * @return
	 * @throws Exception
	 */
	public static Timestamp getCurrTimestamp()throws Exception{
		java.util.Date date = format.parse(getCurrTime());
		return Timestamp.valueOf(format.format(date));
	}
	
	/**
	 * 利用反射注入值
	 * @param clazz
	 * @param rs
	 * @return
	 * @throws Exception
	 */
//	public static BaseVO setBaseValue(Class<?> clazz,ResultSet rs) throws Exception{
		public static IBaseVO setBaseValue(IBaseVO vo,ResultSet rs) throws Exception{
		//			IBaseVO vo = (IBaseVO)clazz.newInstance();
			Class<?> clazz=vo.getClass();
		Map<String,String> map=Pub.getVOFieldType(vo);
		// 根据结果集获得元数据		
		ResultSetMetaData rmd = rs.getMetaData();
		for (int i = 1; i <= rmd.getColumnCount(); i++) {
			// 数据库字段名称
			String columnName =firstLetterToUpper( getStringtoLower(rmd.getColumnName(i)));//小写之后首字母大写
//			logger.debug(columnName+" 是否找到："+columnName);
			if(map.containsKey(columnName)){
				String fieldType=map.get(columnName);//字段类型
				if("INT".equalsIgnoreCase(fieldType)||fieldType.equalsIgnoreCase("BigDecimal")){
					Method m = clazz.getMethod("set"+columnName, new Class[]{BigDecimal.class});
					m.invoke(vo, new Object[]{rs.getBigDecimal(i)});
				}else{
//					logger.debug(columnName+" 是否找到："+rs.findColumn(columnName.toUpperCase()));
					Method m = clazz.getMethod("set"+columnName, new Class[]{String.class});
					m.invoke(vo, new Object[]{rs.getString(i)});
				}
			}
		}
		return vo;
	}
	
	/***
	 * 获取要查询的字段
	 * @param sql
	 * @param vo
	 * @return
	 */
	public static String getAllFields(IBaseVO  vo,boolean flag){
		String sql="";
		Map<String,String> fieldMap=Pub.getVOFieldType(vo);
		Iterator<?> it=fieldMap.keySet().iterator();
		int a=0;
		while(it.hasNext()){
			String key=it.next().toString();
			sql+= flag ? (key+" = ? ") : (key);
			if(a<fieldMap.size()-1) {
				sql+=",";
			}
			a++;
		}
		return sql;
	}
	
	public static String getAllFieldValues(IBaseVO vo,boolean flag){
		String sql="";
		Map<String,String> fieldMap=Pub.getVOFieldType(vo);
		Iterator<?> it=fieldMap.keySet().iterator();
		int a=0;
		while(it.hasNext()){
			String key=it.next().toString();
			sql+= flag ? ( "  ? ") : (key);
			if(a<fieldMap.size()-1) {
				sql+=",";
			}
			a++;
		}
		return sql;
	}
	
	/**
	 * vo更新操作
	 * @param vo
	 * @param stmt
	 * @throws Exception
	 */
	public static void updateBaseValue(IBaseVO vo,PreparedStatement stmt) throws Exception{
		Map<String,String> fieldMap=Pub.getVOFieldType(vo);
		int i=0;
		for (String key : fieldMap.keySet()) {
			Method m = vo.getClass().getMethod("get"+key, new Class[0]);
			Object obj = m.invoke(vo, new Object[0]);
			if(fieldMap.get(key).equalsIgnoreCase("INT")||fieldMap.get(key).equalsIgnoreCase("BigDecimal")) {
				stmt.setBigDecimal(i+1, new BigDecimal(obj.toString()));
			} else {
				stmt.setString(i+1, obj==null?null:obj.toString());
			}
			i++;
		}
	}
	
	/***
	 * 
	 * @param vo
	 * @param stmt
	 * @param keys
	 * @param a
	 * @throws Exception
	 */
	public static void updateBaseValues(IBaseVO vo,PreparedStatement stmt,String [] keys,int a)throws Exception{
		Map<String,String> fieldMap=Pub.getVOFieldType(vo);
		int i=0;
		for (String key : fieldMap.keySet()) {
			Method m = vo.getClass().getMethod("get"+key, new Class[0]);
			Object obj = m.invoke(vo, new Object[0]);
			logger.debug("___________字段数据："+obj);
			String primarykey= UUIDUtil.getUUID();
			if(vo.getPrimaryKey()!=null&& vo.getPrimaryKey().equalsIgnoreCase(key)) {
				if(obj==null||Integer.parseInt(obj.toString())==0){//||Integer.parseInt(obj.toString())==0
					keys[a] =primarykey;//getID();
					stmt.setString(i+1, keys[a]);
					logger.debug("___________主键："+primarykey);
				}else{
//					stmt.setInt(i+1, Integer.parseInt(obj.toString()));
					stmt.setString(i+1, keys[a]);
				}
				Method m1 = vo.getClass().getMethod("set"+key, new Class[]{String.class});
				m1.invoke(vo, new Object[]{primarykey});
			}else {
				if(fieldMap.get(key).equalsIgnoreCase("BigDecimal")||fieldMap.get(key).equalsIgnoreCase("INT")) {
					stmt.setBigDecimal(i+1,new BigDecimal(obj.toString()));
				} else {
					stmt.setString(i+1, (String)obj);
				}
			}
			i++;
		}
	}
	
	/***
	 * 返回信息
	 * @param orderid
	 * @param status
	 * @param content
	 * @return
	 * @throws Exception
	 */
	public static String returnInfo(String orderid,int status,String content,Map<String,String> map) {
		ReturnMsgVo rmv=new ReturnMsgVo(orderid,status,content);//ReturnMsgVo rmv=new ReturnMsgVo(so.getOrderid(),status,content);
		String rexml = null;
		try {
			rexml = VOXMLMapping.toXML(rmv, map, null);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rexml;
	}

	/**
	 * 日志记录
	 * @param baseDao
	 * @param ip
	 * @param so
	 * @param rexml
	 */
	public static void insertLog(PubBaseDao baseDao, String pk_interface, String ip,String type, String orderid,String rexml,String direction,String pairflag, String isResult) {
		LogInterfaceVO reLog=new LogInterfaceVO(pk_interface,Pub.getCurrTime(),ip, type,orderid,direction,pairflag,isResult,rexml);
		baseDao.insert(reLog);
	}
	
	/**
	 * 记录处理结果日志
	 * @param baseDao
	 * @param ip
	 * @param so
	 * @param rexml
	 */
	public static void insertDealResultLog(PubBaseDao baseDao, String pk_interface, String sender,String process, String result,String msg) {
		DealResultLogInterfaceVO reLog=new DealResultLogInterfaceVO(pk_interface,sender,process,result,msg);
		baseDao.insert(reLog);
	}
	
	/**
	 * 日志打印JDBCTemplate的SQL
	 * 
	 * @param sql
	 * @param args
	 * @return 返回实际执行sql
	 */
	public static String logSQL(String sql, Object args[]) {
		if (args == null)
			return sql;
		for (int i = 0; i < args.length; i++) {
			if (args[i] != null) {
				sql = sql.replaceFirst("\\?",
						args[i].toString().length() == 0 ? args[i].toString()
								: "\\'" + args[i].toString() + "'");
			} else {
				sql = sql.replaceFirst("\\?", "null");
			}
		}
		return sql;
	}
	
	/***
	 * 返回的xml文件
	 * @param content
	 * @return
	 */
	public static String returnXml(String content){
		String xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?><returnmsg><result>-1</result><msg>"+content+"</msg></returnmsg>";
		return xml;
	}
	
}
